import type { PageQuery } from '@/types/common/PageQuery'
import type { PageResult } from '@/types/common/PageResult'
import type { Result } from '@/types/common/Result'
import type { DataTableColumns, PaginationProps } from 'naive-ui'
import type { Reactive, Ref } from 'vue'
import { ref } from 'vue'
import usePagination from "@/hooks/usePagination";

/**
 * 转换后的数据
 */
type TransFormerResult<T> = {
  total: number
  pageNum: number
  pageSize: number
  data: T[]
}

/**
 * @param P 初始请求参数
 * @param R 请求返回数据
 * @param T 转换后的数据
 */
type UseTableOptions<P extends PageQuery, R, T = R> = {
  apiFn: (params: P) => Promise<Result<PageResult<R>>>
  initParams?: P
  transformer?: (res: Result<PageResult<R>>) => TransFormerResult<T>
  columns: DataTableColumns<T>
  immediate?: boolean
  onFetched?: (data: Result<PageResult<R>>) => void
}

/**
 * transformer 的默认实现, 默认T = R
 */
const defaultTransformer = <R, T = R>(
  res: Result<PageResult<R>>,
): TransFormerResult<T> => {
  const { total, pageNum, pageSize, records } = res.data
  return {
    total,
    pageNum,
    pageSize,
    data: records as unknown as T[], // 显式转换每个元素
  }
}

/**
 * useTable Hook
 */
export const useTable = <P extends PageQuery, R, T = R>(
  options: UseTableOptions<P, R, T>,
): {
  getData: () => void
  data: Ref<T[]>
  loading: Ref<boolean>
  columns: DataTableColumns<T>
  pagination: Reactive<PaginationProps>
  updateSearchParams: (fn: (params: P) => void) => void
  resetSearchParams: () => void
  apiParams: Ref<P>
} => {
  // 默认分页大小
  const defaultPageSize = 5
  // 解构 options，设置默认值
  const {
    apiFn,
    initParams = { pageNum: 1, pageSize: defaultPageSize }, // 默认值
    transformer = defaultTransformer,
    columns,
    immediate = true,
    onFetched,
  } = options
  // 请求参数
  const apiParams = ref({ pageNum: 1, pageSize: defaultPageSize, ...initParams })

  // 响应式状态
  const data: Ref<T[]> = ref([])
  // 加载状态
  const loading = ref(false)
  // 分页器
  const paginationReactive = usePagination({defaultPageSize: defaultPageSize}, (options) => {
    apiParams.value.pageNum = options.page
  }, (options) => {
    apiParams.value.pageNum = options.page
    apiParams.value.pageSize = options.pageSize
  })


  /**
   * 数据获取函数
   */
  const fetchData = () => {
    loading.value = true
    console.log('apiParams.value', apiParams.value)
    apiFn(apiParams.value)
      .then(res => {
        const transformed = transformer(res)
        data.value = transformed.data
        paginationReactive.itemCount = transformed.total
        paginationReactive.page = transformed.pageNum
        paginationReactive.pageSize = transformed.pageSize
        if (onFetched) {
          onFetched(res)
        }
      })
      .catch(() => {
        window.$message?.error('请求失败')
      })
      .finally(() => {
        loading.value = false
      })
  }
  // 更新搜索参数
  const updateSearchParams = (fn: (params: P) => void) => {
    fn(apiParams.value)
    fetchData()
  }
  // 重置搜索参数
  const resetSearchParams = () => {
    apiParams.value = { pageNum: 1, pageSize: paginationReactive.defaultPageSize }
    fetchData()
  }

  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  immediate && fetchData() // 初始化请求数据

  return {
    getData: fetchData,
    data,
    loading,
    columns,
    pagination: paginationReactive,
    updateSearchParams,
    resetSearchParams,
    apiParams:apiParams.value
  }
}
